package config

import (
	"crypto/rand"
	"crypto/sha256"
	"fmt"
	"os"
	"path/filepath"

	"golang.org/x/crypto/pbkdf2"
	"golang.org/x/crypto/scrypt"
)

// KeyDerivationConfig 密钥派生配置
type KeyDerivationConfig struct {
	Salt       []byte // 盐值
	Iterations int    // 迭代次数
	KeyLength  int    // 密钥长度
}

// PasswordBasedKeyManager 基于密码的密钥管理器
type PasswordBasedKeyManager struct {
	masterKey []byte
	salt      []byte
}

// NewPasswordBasedKeyManager 创建新的基于密码的密钥管理器
func NewPasswordBasedKeyManager() *PasswordBasedKeyManager {
	return &PasswordBasedKeyManager{}
}

// Initialize 初始化密钥管理器
func (pbkm *PasswordBasedKeyManager) Initialize(password string) error {
	// 检查是否存在盐值文件
	saltFile := filepath.Join(ConfigDir, ".salt")

	var salt []byte
	var err error

	if _, err = os.Stat(saltFile); os.IsNotExist(err) {
		// 生成新的盐值
		salt = make([]byte, 32)
		if _, err = rand.Read(salt); err != nil {
			return fmt.Errorf("生成盐值失败: %v", err)
		}

		// 保存盐值
		if writeErr := os.WriteFile(saltFile, salt, 0600); writeErr != nil {
			return fmt.Errorf("保存盐值失败: %v", writeErr)
		}
	} else {
		// 加载现有盐值
		salt, err = os.ReadFile(saltFile)
		if err != nil {
			return fmt.Errorf("加载盐值失败: %v", err)
		}
	}

	// 使用PBKDF2派生密钥
	masterKey := pbkdf2.Key([]byte(password), salt, 100000, 32, sha256.New)

	pbkm.masterKey = masterKey
	pbkm.salt = salt

	return nil
}

// InitializeWithScrypt 使用scrypt初始化（更安全的替代方案）
func (pbkm *PasswordBasedKeyManager) InitializeWithScrypt(password string) error {
	saltFile := filepath.Join(ConfigDir, ".salt")

	var salt []byte

	if _, err := os.Stat(saltFile); os.IsNotExist(err) {
		// 生成新的盐值
		salt = make([]byte, 32)
		if _, err := rand.Read(salt); err != nil {
			return fmt.Errorf("生成盐值失败: %v", err)
		}

		if err := os.WriteFile(saltFile, salt, 0600); err != nil {
			return fmt.Errorf("保存盐值失败: %v", err)
		}
	} else {
		var readErr error
		salt, readErr = os.ReadFile(saltFile)
		if readErr != nil {
			return fmt.Errorf("加载盐值失败: %v", readErr)
		}
	}

	// 使用scrypt派生密钥（更安全的选项）
	masterKey, scryptErr := scrypt.Key([]byte(password), salt, 32768, 8, 1, 32)
	if scryptErr != nil {
		return fmt.Errorf("派生密钥失败: %v", scryptErr)
	}

	pbkm.masterKey = masterKey
	pbkm.salt = salt

	return nil
}

// GetMasterKey 获取主密钥
func (pbkm *PasswordBasedKeyManager) GetMasterKey() ([]byte, error) {
	if pbkm.masterKey == nil {
		return nil, fmt.Errorf("密钥管理器未初始化")
	}
	return pbkm.masterKey, nil
}

// ChangePassword 更改密码（重新派生密钥）
func (pbkm *PasswordBasedKeyManager) ChangePassword(oldPassword, newPassword string) error {
	// 验证旧密码
	oldKey := pbkdf2.Key([]byte(oldPassword), pbkm.salt, 100000, 32, sha256.New)

	// 检查当前密钥是否匹配
	if string(oldKey) != string(pbkm.masterKey) {
		return fmt.Errorf("旧密码不正确")
	}

	// 加载所有现有配置
	users, err := LoadAllUserConfigs(pbkm.masterKey)
	if err != nil {
		return fmt.Errorf("加载用户配置失败: %v", err)
	}

	// 使用新密码派生新密钥
	newKey := pbkdf2.Key([]byte(newPassword), pbkm.salt, 100000, 32, sha256.New)

	// 使用新密钥重新加密所有配置
	for _, user := range users {
		if err := SaveUserConfig(user, newKey); err != nil {
			return fmt.Errorf("重新加密用户配置失败: %v", err)
		}
	}

	pbkm.masterKey = newKey
	return nil
}
